/*
	Copyright (C) 2010 Salil Bhagurkar

	This file is part of k3

	k3 is free software: you can redistribute it and/or modify
	it under the terms of the GNU Lesser General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	k3 is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public License
	along with k3.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <shared.h>

/**
vmdrv console implementation
Currently just a wrapper
*/
static int vmdrvconsole_string_read(struct fs *referrer, struct fs *this, struct buffer *buf, u32 offset, u32 count)
{
	char out_buf[2], c;
	u32 i = 0;
	int e;
	out_buf[1] = '\0';
	count = MAX_FS_NAME_LEN;
	struct buffer *mybuf = buffer_create(0);
	while(1) {
		e = fs_read(referrer, fsparse_get_relative(this->system->fs->parent, "in"), mybuf, 0, 1);
		c = *((char *)mybuf->data);
		if(e)
			return e;
		if(c == '\n') {
			break;
		} else if(c == '\b') {
			if(i > 0) {
				buffer_write_data(buf, "\0", --i, 1);
				buf->len--;
				out_buf[0] = c;
				printk(out_buf);
			}
		} else {
			if(i < (count - 1)) {
				buffer_write_data(buf, &c, i++, 1);
				out_buf[0] = c;
				printk(out_buf);
			}
		}
	}
	buffer_free(mybuf);
	return 0;
}

static int vmdrvconsole_string_write(struct fs *referrer, struct fs *this, struct buffer *buf, u32 offset, u32 count)
{
	return fs_write(referrer, fsparse_get_relative(this->system->fs->parent, "out"), buf, offset, count);
}

static void vmdrvconsole_get_devices(struct fs *console_fs)
{
	struct fs *in_dev, *out_dev;
	in_dev = fs_create(FSFLAGS_VMDRV, "in");
	in_dev->system = fsparse_get("/devices/class/input/keyb")->system;
	out_dev = fs_create(FSFLAGS_VMDRV, "out");
	out_dev->system = fsparse_get("/devices/printk")->system;
	fs_link(console_fs, in_dev);
	fs_link(console_fs, out_dev);

	struct fs *string_dev;
	string_dev = fs_create(FSFLAGS_VMDRV, "string");
	string_dev->system = fs_create_system(0, vmdrvconsole_string_read, vmdrvconsole_string_write, dummy, string_dev);
	fs_link(console_fs, string_dev);
}

int vmdrvconsole_init()
{
	dprint(D_PROG, "console", "Initialize vmdrv");
	struct fs *console_fs;
	console_fs = fs_create(FSFLAGS_VMDRV, "console");
	fs_link(fsparse_get("/vmdrv"), console_fs);
	vmdrvconsole_get_devices(console_fs);
	return 0;
}
